home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl
- #
- #Perl-based menu system
- #
- #Uses dialog for actual IO.
- #
- #Either pass it a menu file, or it will use ~/.menurc or /etc/menurc
- #
- #This program is Copyright (C) 1995 by Joey Hess, and may be freely
- #distributed under the terms of the GNU public license.
- #
- #Send comments, questions, and bug reports to Joey Hess <jeh22@cornell.edu>
- #
-
- #You may need to change this to some other directory. It is a temporary
- #directory, and all users should have write access to it.
- $tmp='/tmp';
-
- #If your clear command isn't on the path, you should change this to point
- #to it. Or, you can change this to change the default clear command.
- $clearcmd='clear';
-
- #This is displayed as the "background title" in all dialogs of Pdmenu.
- #Feel free to change it.
- $btitle='Pdmenu 0.2 by Joey Hess <jeh22@cornell.edu>';
-
- #This is the default directory where color definition files for Pdmenu
- #are located.
- $colordir='/usr/local/lib/pdmenu/';
-
- #--End of user configurable section. Code follows.--#
-
- $tmp.='/.menu-'.$env{USER}.time;
- $cleartext=`$clearcmd`;
- $keywordlist{show}=1;
- $keywordlist{exec}=2;
- $|=1;
-
- #Interactively fill in a blank, return the value
- #
- sub InteractiveFillin { my $title=shift; my $desc=shift;
- my $cmd="dialog --backtitle \"$btitle\" --title \"$title\" --inputbox \"$desc\" 8 75";
- my $a=system "$cmd 2> $tmp";
- open (IN,"<$tmp");
- @ret=<IN>;
- close IN;
- unlink $tmp;
- return "@ret";
- }
-
-
- #Run a menu command
- #
- sub RunCommand { my $command_type=shift; my $command=shift; my $fields=shift;
- if ($command_type eq 1) {
- do ShowMenu($command);
- }
- elsif ($command_type eq 2) {
- #process the fields
- $_=$fields;
- if (/i/) { #interactively fill in parts of the command line.
- $command=~s#%(.*?)%(.*?)%#&InteractiveFillin($1,$2)#eg;
- }
- if (/c/) { print $cleartext }
- #run the program.
- system $command;
- }
- if (/p/) { #pause
- print "\nHit Enter to return to Pdmenu..";
- $_=<>;
- }
- }
-
- #Just returns the greater of the two values.
- #
- sub PumpUp { my ($a,$b)=@_;
- if ($a > $b) { return $a } else { return $b }
- }
-
- #Read and parse a menu file.
- #
- sub ReadMenu { my $fn=shift;
- my $count=0;
- my $l=0;
- my $filler=0;
- open (IN,"<$fn") || exit print "Unable to open $fn.\n";
- while (<IN>) {
- $l++;
- s/\n$//;
- s/\t/ /g;
- tr/ / /s;
- s/^ //;
- s/ $//;
- if ((/^#/ eq '') && ($_ ne '')) {
- if (/menu:/i ne '') { #new menu def
- my ($m,$mn,$colordef,$title,$desc)=split(/:/,$_,6);
- $menu=$mn;
- $count=0;
- $menu=~tr/A-Z/a-z/;
- $menus{$menu}[0]=$title;
- $menus{$menu}[1]=$desc;
- $menus{$menu}[2]=30;
- $menus{$menu}[2]=PumpUp($menus{$menu}[2],length($title)+5);
- $menus{$menu}[2]=PumpUp($menus{$menu}[2],length($desc)+5);
- if ($colordef) {
- if (-e $colordef) {
- $menus{$menu}[3]=$colordef;
- }
- elsif (-e $colordir.$colordef) {
- $menus{$menu}[3]=$colordir.$colordef;
- }
- else {
- exit print "Color definition file $colordef does not exist.\n";
- }
- }
- $menucount{$menu}=0;
- $filler=0;
- }
- else {
- my ($keyword,$hotkey,$desc,$command,$fields)=split(/:/,$_,5);
- $keyword=~tr/A-Z/a-z/;
- my $k=$keywordlist{$keyword};
- unless ($k) {
- exit print "Bad keyword in line $l: \"$keyword\"\n";
- }
- if (!$hotkey) { $hotkey=++$filler }
- $menu{$menu}[0][++$count]=$k;
- $menu{$menu}[1][$count]=$hotkey;
- $menu{$menu}[2][$count]=$desc;
- $menus{$menu}[2]=PumpUp($menus{$menu}[2],length($desc)+9);
- $menu{$menu}[3][$count]=$command;
- $menu{$menu}[4][$count]=$fields;
- $menucount{$menu}=$menucount{$menu}+1;
- }
- }
- }
- close IN;
- }
-
- #Display a menu and handle its output. Pass the name of the menu to show.
- #
- sub ShowMenu { my $name=shift;
- my $a=0;
-
- if (!$menucount{$name}) { exit print "Tried to display undefined menu: \"$name\"\n"; }
- #set dialog colors
- #build command for dialog.
- my $height=$menucount{$name}+7; #get dialog height.
- if (($height <=> 22) eq 1) { $height=21 }
- my $mheight=$height-7;
- my $cmd="dialog --backtitle \"$btitle\" --title \"$menus{$name}[0]\" --menu \"$menus{$name}[1]\" $height $menus{$name}[2] $mheight ";
- foreach (1..$menucount{$name}) {
- $cmd.="\"$menu{$name}[1][$_]\" \"$menu{$name}[2][$_]\" ";
- }
- while ($a eq 0) {
- $ENV{DIALOGRC}=$menus{$name}[3];
- $a=system "$cmd 2> $tmp";
- open (IN,"<$tmp");
- @ret=<IN>;
- close IN;
- unlink $tmp;
-
- if ($a eq '0') {
- foreach (1..$menucount{$name}) {
- if ($ret[0] eq $menu{$name}[1][$_]) {
- do RunCommand($menu{$name}[0][$_],$menu{$name}[3][$_],$menu{$name}[4][$_]);
- }
- }
- }
- else {
- if ($ret[0] ne '') { exit print "Dialog error!\n"; }
- }
- }
- }
-
- $fn=shift;
- if ($fn) { #load a specific file.
- while ($fn) {
- do ReadMenu($fn);
- $fn=shift;
- }
- }
- else { #load up one of the default menu files
- if (-e $env{$HOME}.'.pdmenurc') {
- do ReadMenu($env{$HOME}.'.pdmenurc');
- }
- elsif (-e '/etc/pdmenurc') {
- do ReadMenu('/etc/pdmenurc');
- }
- else {
- exit print "Unable to read pdmenurc!\n";
- }
- }
-
- do ShowMenu('main');
-
- print $cleartext; #clean up screen.
-